package com.sh.data.engine.web.webapi.controller.normalization;

import com.sh.data.engine.application.model.dto.base.PagerResponse;
import com.sh.data.engine.application.model.dto.normalization.modeldesign.DictionaryResponse;
import com.sh.data.engine.application.model.dto.normalization.modeldesign.ModelListResponse;
import com.sh.data.engine.application.model.dto.normalization.modeldesign.ModelResponse;
import com.sh.data.engine.application.model.dto.normalization.modeldesign.StorageResponse;
import com.sh.data.engine.application.model.dto.normalization.research.ThemeResponse;
import com.sh.data.engine.application.model.request.normalization.DeleteModelRequest;
import com.sh.data.engine.application.model.request.normalization.SaveModelRequest;
import com.sh.data.engine.application.model.request.normalization.SaveNewModelRequest;
import com.sh.data.engine.application.model.request.normalization.SaveThemeRequest;
import com.sh.data.engine.application.service.normalization.ModelApplicationService;
import com.sh.data.engine.domain.annotation.LogExecution;
import com.sh.data.engine.domain.annotation.userlog.Business;
import com.sh.data.engine.domain.annotation.userlog.EngineOperation;
import com.sh.data.engine.domain.dataasset.service.TblPropService;
import com.sh.data.engine.domain.normalization.modeldesign.cdm.service.TblRelationService;
import com.sh.data.engine.domain.normalization.modeldesign.model.model.param.SaveModelParam;
import com.sh.data.engine.domain.normalization.modeldesign.model.service.ModelService;
import com.sh.data.engine.domain.normalization.research.themedesign.service.ThemeService;
import com.sh.data.engine.domain.util.ConvertUtil;
import com.sh.data.engine.web.webapi.controller.base.response.RestResponseEntity;
import io.swagger.v3.oas.annotations.Operation;
import io.swagger.v3.oas.annotations.Parameter;
import io.swagger.v3.oas.annotations.media.Schema;
import io.swagger.v3.oas.annotations.tags.Tag;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.validation.annotation.Validated;
import org.springframework.web.bind.annotation.*;

import javax.validation.Valid;
import java.util.List;
import java.util.Optional;

/**
 * @author : changkong
 * @date : 2022/1/17
 */
@Validated
@Tag(name = "规范设计-(贴源,公共,应用,其他)四种模型", description = "(贴源,公共,应用,其他)四种模型API")
@RestController
@RequestMapping("/normalization/modeldesign/model")
public class ModelController {

    @Autowired
    private ModelService modelService;
    @Autowired
    private TblRelationService tblRelationService;
    @Autowired
    private ThemeService themeService;
    @Autowired
    private TblPropService tblPropService;

    @Autowired
    private ModelApplicationService modelApplicationService;

    //    @AuthorityAnnotation(menuId = MenuEnumNew.TYMX, readWriteStatus = 0, isAdd = 1)
    @GetMapping("/treeThemes")
    @Operation(summary = "主题树形结构")
    public RestResponseEntity<List<ThemeResponse>> treeThemes() {
        var result = modelApplicationService.treeThemes();
        return RestResponseEntity.success(result);
    }

    //    @AuthorityAnnotation(menuId = MenuEnumNew.TYMX, readWriteStatus = 1, isAdd = 1)
    @PostMapping("/saveTheme")
    @LogExecution(operation = EngineOperation.ADD_UPDATE, business = Business.主题域)
//    @Log(
//        business = Business.主题域,
//        operation = Operation.ADD_UPDATE)
    @Operation(summary = "新建或编辑主题")
    public RestResponseEntity<Boolean> saveTheme(@Valid @RequestBody SaveThemeRequest themeRequest) {
        var result = modelApplicationService.saveTheme(themeRequest);
        return RestResponseEntity.success(result);
    }

    /**
     * 模型页面, 主题菜单列表
     *
     * @return
     */
//    @AuthorityAnnotation(menuId = MenuEnumNew.TYMX, readWriteStatus = 0, isAdd = 1)
    @GetMapping("/getStorageType")
    @Operation(summary = "获取当前存储类型")
    public RestResponseEntity<StorageResponse> getStorageType() {
        var result = modelApplicationService.getStorageType();
        return RestResponseEntity.success(result);
    }

    //    @AuthorityAnnotation(menuId = MenuEnumNew.TYMX, readWriteStatus = 0, isAdd = 1)
    @GetMapping("/getDictionaryList")
    @Operation(summary = "获取数据标准列表")
    public RestResponseEntity<List<DictionaryResponse>> getDictionaryList() {
        var result = modelApplicationService.getDictionaryList();
        return RestResponseEntity.success(result);
    }

    //    @AuthorityAnnotation(menuId = MenuEnumNew.TYMX, readWriteStatus = 0, isAdd = 1)
    @GetMapping("/getSchemas")
    @Operation(summary = "获取sap schemas")
    public RestResponseEntity<List<String>> getSchemas() {
        var result = modelApplicationService.getSchemas();
        return RestResponseEntity.success(result);
    }

    /**
     * 模型页面, 主题菜单列表
     *
     * @return
     */
//    @AuthorityAnnotation(menuId = MenuEnumNew.TYMX, readWriteStatus = 0, isAdd = 1)
    @GetMapping("/getThemeList")
    @Operation(summary = "模型页面, 主题菜单列表")
    public RestResponseEntity<List<ThemeResponse>> getThemeList(
        @Parameter(description = "modelType", example = "ods public apply other")
        @RequestParam(required = true)
        String modelType) {
        var result = modelApplicationService.getThemeList(modelType);
        return RestResponseEntity.success(result);
    }

    /**
     * 模型页面, 主题菜单列表
     *
     * @return
     */
//    @AuthorityAnnotation(menuId = MenuEnumNew.TYMX, readWriteStatus = 0, isAdd = 1)
    @GetMapping("/getThemeMenus")
    @Operation(summary = "模型页面, 主题菜单列表")
    public RestResponseEntity<List<ThemeResponse>> getThemeMenus(
        @Parameter(description = "modelType", example = "ods public apply other")
        @RequestParam(required = true)
        String modelType) {
        var result = modelApplicationService.getThemeMenus(modelType);
        return RestResponseEntity.success(result);
    }

    /**
     * 按照类型返回模型列表
     *
     * @param modelType
     * @return
     */
//    @AuthorityAnnotation(menuId = MenuEnumNew.TYMX, readWriteStatus = 0, isAdd = 1)
    @GetMapping("/getModelListByType")
    @Operation(summary = "按类型获取模型列表")
    public RestResponseEntity<PagerResponse<ModelListResponse>> getModelListByType(
        @Parameter(description = "当前页", schema = @Schema(defaultValue = "1"))
        @RequestParam(required = false, defaultValue = "1")
        Integer pageNum,
        @Parameter(description = "每页大小", schema = @Schema(defaultValue = "10"))
        @RequestParam(required = false, defaultValue = "10")
        Integer pageSize,
        @Parameter(description = "themeId") @RequestParam(required = true) Optional<Long> themeId,
        @Parameter(description = "modelType", example = "ods public apply other cdm")
        @RequestParam(required = true)
        String modelType,
        @Parameter(description = "搜索条件", example = "模型中文名 英文名 创建人") @RequestParam(required = false)
        String search) {
        var result = modelApplicationService.getModelList(pageNum, pageSize, themeId, modelType, search);
        return RestResponseEntity.success(result);
    }

    /**
     * 按照类型返回模型列表-不分页
     *
     * @param modelType
     * @return
     */
//    @AuthorityAnnotation(menuId = MenuEnumNew.TYMX, readWriteStatus = 0, isAdd = 1)
    @GetMapping("/getAllModelsByType")
    @Operation(summary = "按类型获取模型列表-不分页")
    public RestResponseEntity<List<ModelListResponse>> getModelListByType(
        @Parameter(description = "themeId") @RequestParam(required = false) Long themeId,
        @Parameter(description = "modelType", example = "ods public apply other cdm")
        @RequestParam(required = true)
        String modelType,
        @Parameter(description = "搜索条件", example = "模型中文名 英文名 创建人") @RequestParam(required = false)
        String search) {
        var result = modelApplicationService.getAllModelList(themeId, modelType, search);
        return RestResponseEntity.success(result);
    }

    /**
     * 按照类型返回模型列表
     *
     * @param pageNum
     * @param pageSize
     * @return
     */
//    @AuthorityAnnotation(menuId = MenuEnumNew.TYMX, readWriteStatus = 0, isAdd = 1)
    @GetMapping("/getCDMList")
    @Operation(summary = "获取CDM模型列表")
    public RestResponseEntity<PagerResponse<ModelListResponse>> getCDMList(
        @Parameter(description = "当前页", schema = @Schema(defaultValue = "1"))
        @RequestParam(required = false, defaultValue = "1")
        Integer pageNum,
        @Parameter(description = "每页大小", schema = @Schema(defaultValue = "10"))
        @RequestParam(required = false, defaultValue = "10")
        Integer pageSize,
        @Parameter(description = "themeId") @RequestParam(required = true) Optional<Long> themeId,
        @Parameter(description = "搜索条件", example = "模型中文名 英文名 创建人") @RequestParam(required = false)
        String search) {
        var result = modelApplicationService.getCDMList(pageNum, pageSize, themeId, search);
        return RestResponseEntity.success(result);
    }

    /**
     * 按照id获取单个tbl
     *
     * @return
     */
//    @AuthorityAnnotation(menuId = MenuEnumNew.TYMX, readWriteStatus = 0, isAdd = 1)
    @GetMapping("/getModelByTblId")
    @Operation(summary = "获取单个模型id")
    public RestResponseEntity<ModelResponse> getTblPropById(
        @Parameter(description = "tblId") @RequestParam(required = true) long tblId) {
        var result = modelApplicationService.getModelByTblId(tblId);
        return RestResponseEntity.success(result);
    }

    /**
     * 按照id获取单个模型
     *
     * @return
     */
//    @RequireSecretLevel(bizId = "#modelId", evalSecretFunc = "getDataLevelIdByModelId")
//    @AuthorityAnnotation(menuId = MenuEnumNew.TYMX, readWriteStatus = 0, isAdd = 1)
    @GetMapping("/getModelById")
    @Operation(summary = "获取单个模型")
    public RestResponseEntity<ModelResponse> getModelById(
        @Parameter(description = "modelId") @RequestParam(required = true) Long modelId) {
        var result = modelApplicationService.getModelByModelId(modelId);
        return RestResponseEntity.success(result);
    }

    /**
     * 按照id获取单个模型
     *
     * @return
     */
//    @RequireSecretLevel
//    @AuthorityAnnotation(menuId = MenuEnumNew.TYMX, readWriteStatus = 0, isAdd = 1)
    @GetMapping("/getModelByName")
    @Operation(summary = "获取单个模型")
    public RestResponseEntity<ModelResponse> getModelByName(
        @Parameter(description = "schema") @RequestParam(required = true) String schema,
        @Parameter(description = "tableName") @RequestParam(required = true) String tableName) {
        var result = modelApplicationService.getModelByName(schema, tableName);
        return RestResponseEntity.success(result);
    }

    /**
     * 删除模型
     *
     * @return
     */
//    @RequireSecretLevel(bizId = "#deleteModelRequest.modelId", evalSecretFunc = "getDataLevelIdByModelId")
//    @AuthorityAnnotation(menuId = MenuEnumNew.TYMX, readWriteStatus = 1, isAdd = 1)
    @PostMapping("/deleteModelById")
    @LogExecution(operation = EngineOperation.DEL, business = Business.模型设计)
//    @Log(
//        business = Business.模型设计,
//        operation = Operation.DEL)
    @Operation(summary = "删除单个模型")
    public RestResponseEntity<Boolean> deleteModelById(
        @Validated @RequestBody DeleteModelRequest deleteModelRequest) {
        var result = modelApplicationService.deleteModel(deleteModelRequest);
        return RestResponseEntity.success(result);
    }

    //    @AuthorityAnnotation(menuId = MenuEnumNew.TYMX, readWriteStatus = 1, isAdd = 1)
    @PostMapping("/saveNewModel")
    @LogExecution(operation = EngineOperation.ADD, business = Business.模型设计)
//    @Log(
//        business = Business.模型设计,
//        operation = org.springframework.expression.Operation.ADD)
    @Operation(summary = "新建模型")
    public RestResponseEntity<Boolean> saveModel(
        @Validated @RequestBody SaveNewModelRequest saveNewModelRequest) {
        var result = modelApplicationService.saveNewModel(saveNewModelRequest);
        return RestResponseEntity.success(result);
    }

    //    @RequireSecretLevel(bizId = "#saveModelRequest.modelId", evalSecretFunc = "getDataLevelIdByModelId")
//    @AuthorityAnnotation(menuId = MenuEnumNew.TYMX, readWriteStatus = 1, isAdd = 1)
    @PostMapping("/saveModel")
    @LogExecution(operation = EngineOperation.UPDATE, business = Business.模型设计)
//    @Log(
//        business = Business.模型设计,
//        operation = Operation.UPDATE)
    @Operation(summary = "修改模型")
    public RestResponseEntity<Boolean> saveModel(@Validated @RequestBody SaveModelRequest saveModelRequest) {
        List<SaveModelParam.Field> paramFields =
            ConvertUtil.copyProperties(saveModelRequest.getFields(), SaveModelParam.Field.class);
        SaveModelParam saveModelParam =
            ConvertUtil.copyProperties(saveModelRequest, SaveModelParam.class);
        saveModelParam.setFields(paramFields);
        modelService.saveModel(saveModelParam);
        return RestResponseEntity.success(true);
    }

    @GetMapping("/searchTable")
    @Operation(summary = "根据表名模糊查询，按时间倒序查询第一个表信息，测试专属")
    public RestResponseEntity<List<ModelListResponse>> searchTable(String tableName) {
        var result = modelApplicationService.searchTable(tableName);
        return RestResponseEntity.success(result);
    }
}
